#! /usr/bin/python
#                   _ooOoo_                     
#                  o8888888o                    
#                  88" . "88                    
#                  (| -_- |)                    
#                  O\  =  /O                    
#               ____/`---'\____                 
#             .'  \\|     |//  `.               
#            /  \\|||  :  |||//  \              
#           /  _||||| -:- |||||-  \             
#           |   | \\\  -  /// |   |             
#           | \_|  \---/  |   |             
#           \  .-\__  `-`  ___/-. /             
#         ___`. .'  /--.--\  `. . __            
#      ."" '<  `.___\_<|>_/___.'  >'"".      
#     | | :  `- \`.;`\ _ /`;.`/ - ` : | |       
#     \  \ `-.   \_ __\ /__ _/   .-` /  /       
#======`-.____`-.___\_____/___.-`____.-'======  
#                   `=---='                     
#^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^  
#         Buddha bless me for no bug            
#                                               
####################################################################################
#   Filename    :  StarMisc.py                                                      
#   Author      :  Shawn Tan                                                        
#   Date        :  2017.4.1                                                        
#   Description :                                                                   
#   History     :  2017.4.1             creat the document            Shawn Tan    
####################################################################################

import os,random,shutil,stat
from collections import OrderedDict
from StarRE      import *
from StarVar     import *
from StarInfo    import *
from StarEda     import *

__author__ = 'ST_CAT'

def solve_dir(option, TYPE, t, seed='0'):

   dir_op_list = [
   'BUILD_REGRESSION',
   'BUILD_GROUP',
   'BUILD_TEST',
   'BUILD_PROFILE',
   'BUILD_VERDI',
   'FIND_REGRESSION',
   'FIND_GROUP',
   'FIND_TEST',
   'FIND_PROFILE',
   'FIND_VERDI',
   'FIND_GROUP_ROOT',
   'FIND_TEST_ROOT'
   ]

   assert TYPE in dir_op_list, exec000+' : '+TYPE 

   cwd=os.getcwd()

   if len(t.attributes['DIR']['top_dir']) == 0:
     ReDir = cwd+'/build'
   else:
     ReDir = cwd+'/'+t.attributes['DIR']['top_dir'][0]

   if len(t.attributes['DIR']['comp_dir']) == 0:
     group_dir = ReDir+'/'+t.sessionname+'_'+t.groupname 
   else:
     group_dir = t.attributes['DIR']['comp_dir'][0]       

   if 'REGRESSION' in TYPE:
     if 'BUILD' in TYPE: 
       if not os.path.exists(ReDir):
         os.makedirs(ReDir)
       os.putenv('REGRESSION_PATH', cwd)

     elif 'FIND' in TYPE: 
       pass

     return ReDir

   elif 'GROUP' in TYPE: 

     if 'BUILD' in TYPE: 
       compile_dir = group_dir+'/compile'
       if not os.path.exists(compile_dir):
         os.makedirs(compile_dir)
       if os.path.isfile(compile_dir+'/compile_shell'):
         os.remove(compile_dir+'/compile_shell')

       compile_shell = file(compile_dir+'/compile_shell', 'w')
       line = '#! /usr/bin/env bash\n'
       compile_shell.write(line)
       compile_shell.close()
       os.chmod(compile_dir+'/compile_shell', stat.S_IRWXU)


     elif 'FIND' in TYPE: 
       if 'ROOT' in TYPE:
         return group_dir
       else:
         pass

     return group_dir+'/compile'

   elif 'TEST' in TYPE: 

     if len(t.attributes['DIR']['sim_dir']) == 0:
       sim_root = group_dir+'/sim/'+t.testname
     else:
       sim_root = group_dir+'/sim/'+t.attributes['DIR']['sim_dir'][0]

     sim_dir = sim_root+'/'+str(seed)

     if 'BUILD' in TYPE: 
       if not os.path.exists(sim_dir):
         os.makedirs(sim_dir)

       if os.path.isfile(sim_dir+'/simulation_shell'):
         os.remove(sim_dir+'/simulation_shell')

       simulation_shell = open(sim_dir+'/simulation_shell', 'w')
       line = '#! /usr/bin/env bash\n'
       line = line+'source '+sim_dir+'/env.sh\n'
       simulation_shell.write(line)
       simulation_shell.close()
       os.chmod(sim_dir+'/simulation_shell', stat.S_IRWXU)

       if os.path.isfile(sim_dir+'/env.sh'):
         os.remove(sim_dir+'/env.sh')

       env_csh = open(sim_dir+'/env.sh', 'w')
       env_csh.write('#! /usr/bin/env bash \n')
       env_csh.close()
       os.chmod(sim_dir+'/env.sh', stat.S_IRWXU)

     elif 'FIND' in TYPE: 
       if 'ROOT' in TYPE:
         return sim_root 
       else:
         pass

     return sim_dir

   elif 'PROFILE' in TYPE: 
     profile_dir = group_dir+'/profile'

     if 'BUILD' in TYPE:
       if not os.path.exists(profile_dir):
         os.makedirs(profile_dir)

     elif 'FIND' in TYPE:
       pass
     
     return profile_dir

   elif 'VERDI' in TYPE: 
     verdi_dir = group_dir+'/verdi'

     if 'BUILD' in TYPE:
       if not os.path.exists(verdi_dir):
         os.makedirs(profile_dir)

     elif 'FIND' in TYPE:
       pass
     
     return verdi_dir

def script_writer(option, t, index, TYPE, seed):
  
  # create the star tools command line for simulation

  script_comp_list = [
  'RTL',
  'VIP',
  'TB',
  'ELAB'
  ]

  script_other_list = [
  'SIM',
  'SCAN',
  'VERDI',
  'ENV'
  ]

  assert ((TYPE in script_comp_list) or (TYPE in script_other_list)), exec003+TYPE

  if TYPE in script_comp_list:

    rtl_comp_log = option.COMP_RTL_LOG
    vip_comp_log = option.COMP_VIP_LOG
    tb_comp_log  = option.COMP_TB_LOG
    elab_log  = option.ELAB_LOG

    compile_dir  = solve_dir(option, 'FIND_GROUP', t, 0)  

    rtl_comp_opt = ''
    for i in t.attributes['COMPILE']['rtl_comp_opt']: 
      rtl_comp_opt = rtl_comp_opt+' '+i

    vip_comp_opt = ''
    for i in t.attributes['COMPILE']['vip_comp_opt']: 
      vip_comp_opt = vip_comp_opt+' '+i

    tb_comp_opt  = ''
    for i in t.attributes['COMPILE']['tb_comp_opt']: 
      tb_comp_opt = tb_comp_opt+' '+i

    for i in t.attributes['COMPILE']['define_opt']:
      rtl_comp_opt = rtl_comp_opt+' '+i
      vip_comp_opt = vip_comp_opt+' '+i
      tb_comp_opt  = tb_comp_opt+' '+i

    for i in t.attributes['COMPILE']['comp_opt']:
      rtl_comp_opt = rtl_comp_opt+' '+i
      vip_comp_opt = vip_comp_opt+' '+i
      tb_comp_opt  = tb_comp_opt+' '+i

    if option.PROFILE_TIME or option.PROFILE_MEM:
      rtl_comp_opt = rtl_comp_opt+' '+basic_profile_dict[option.VENDOR]
      vip_comp_opt = vip_comp_opt+' '+basic_profile_dict[option.VENDOR]
      tb_comp_opt  = tb_comp_opt+' '+basic_profile_dict[option.VENDOR]

    if len(t.attributes['COMPILE']['timescale']) !=0:
     rtl_comp_opt = rtl_comp_opt+' '+t.attributes['COMPILE']['timescale'][0]
     vip_comp_opt = vip_comp_opt+' '+t.attributes['COMPILE']['timescale'][0]
     tb_comp_opt  = tb_comp_opt+' '+t.attributes['COMPILE']['timescale'][0]

    elab_opt = basic_elab_dict[option.VENDOR]

    for i in t.attributes['ELABORATION'].keys():
      for j in t.attributes['ELABORATION'][i]:
          elab_opt = elab_opt+' '+j

    if TYPE=='RTL':
      line = 'star_dpc -cmp_dir '+compile_dir

      if len(t.attributes['COMPILE']['rtl_file_list']) == 0:
        rtl_source = '' 
      else:
        rtl_source = ' -f '+t.attributes['COMPILE']['rtl_file_list'][0]  

      if len(t.attributes['CONTROL']['git_cfg']) == 0:
        rtl_source = rtl_source
      else:
        rtl_source = rtl_source+' -c '+t.attributes['CONTROL']['git_cfg'][0]  
      assert rtl_source != '', exec004

      line = line+' '+rtl_source

      line = line+' -cmp_opt "'+rtl_comp_opt+'"'

      line = line+' -sum_log '+rtl_comp_log

    elif TYPE=='VIP':
      line=''
      if len(t.attributes['COMPILE']['vip_file_list']) !=0:
        line = 'star_base -cmp_dir '+compile_dir
        line = line+' -comp '

        if len(t.attributes['COMPILE']['vip_file_list']) == 0:
          vip_source = ''
        else:
          vip_source = ' -f '+t.attributes['COMPILE']['vip_file_list'][0]  

        assert vip_source != '', exec005

        line=line+vip_source

        line = line+' -comp_opt "-sverilog -ntb_opts uvm '+vip_comp_opt+'"'
        line = line+' -comp_log '+'uvm_comp.log\n'
      
      line=line+'star_dpc -cmp_dir '+compile_dir
      line=line+vip_source 

      line=line+' -cmp_opt "-sverilog '+vip_comp_opt+' '+basic_comp_dict[option.VENDOR]+'"'
      line=line+' -sum_log '+vip_comp_log

    elif TYPE=='TB':
      line='star_dpc  -cmp_dir '+compile_dir
      assert len(t.attributes['COMPILE']['tb_file_list']) != 0, exec006
      line = line+' -f '+t.attributes['COMPILE']['tb_file_list'][0]
      line = line+' -cmp_opt "'+tb_comp_opt+" "+basic_comp_dict[option.VENDOR]+'"' 
      line = line+' -sum_log '+tb_comp_log
    elif TYPE=='ELAB':
      line='star_base -elab -cmp_dir '+compile_dir
      line=line+' -elab_opt "'+elab_opt+'"'
      line=line+' -elab_log '+elab_log
  
  elif TYPE in script_other_list:
    # write the simulation script command line  
    sim_log = option.SIM_LOG
    sim_dir = solve_dir(option, 'FIND_TEST', t, seed)
    compile_dir = solve_dir(option, 'FIND_GROUP', t, seed)
    #profile_dir = 

    if TYPE == 'SIM':
      line =  'star_base -sim -cmp_dir '+compile_dir+' -sim_dir '+sim_dir

      sim_opt=''
      for i in t.attributes['SIMULATION']: 
        for j in t.attributes['SIMULATION'][i]:
          sim_opt = sim_opt+' '+j

      sim_opt = sim_opt+basic_sim_dict[option.VENDOR]+' +RANDOM_SEED='+seed

      if option.GLS:
        sim_opt = sim_opt+gls_sim_dict[option.VENDOR]

      if option.UCLI or len(t.attributes['SIMULATION']['waveform']) != 0:
        sim_opt = sim_opt+tcl_sim_dict[option.VENDOR]+t.attributes['SIMULATION']['waveform'][0]

      if option.PROFILE_TIME:
        sim_opt = sim_opt+basic_sim_profile_mem_dict[option.VENDOR]+\
                  solve_dir[(option, 'FIND_PROFILE', t, seed)]+'/'+\
                  t.sessionname+'_'+t.groupname+'_'+t.testname+'_'+seed

      if option.PROFILE_MEM:
        sim_opt = sim_opt+basic_sim_profile_time_dict[option.VENDOR]+\
                  solve_dir[(option, 'FIND_PROFILE', t, seed)]+'/'+\
                  t.sessionname+'_'+t.groupname+'_'+t.testname+'_'+seed

      line = line+' -sim_opt "'+sim_opt+'" -seed '+seed+' -sim_log '+sim_log

      if not option.NoQuiet:
        line = line+' -q '

      if option.LOG_ON:
        line = "xterm -title "+t.testname+"_"+seed+" -fg green -bg black -e '"+\
               line+"'"

      if len(t.attributes['SCRIPT']['pre_run_script']) !=0 :
        line=t.attributes['SCRIPT']['pre_run_script'][0]+'\n'+\
             line

      if len(t.attributes['SCRIPT']['post_run_script']) !=0:
        line=line+'\n'+t.attributes['SCRIPT']['post_run_script'][0]

    elif TYPE == 'SCAN':

      scan_sim_log = sim_dir+'/'+sim_log

      if len(t.attributes['SCRIPT']['pass_cfg']) != 0:
        pass_cfg = ' -pass_cfg_file '+t.attributes['SCRIPT']['pass_cfg'][0] 
      else:
        pass_cfg = ''

      if len(t.attributes['SCRIPT']['fail_cfg']) != 0:
        fail_cfg = ' -fail_cfg_file '+t.attributes['SCRIPT']['fail_cfg'][0] 
      else:
        fail_cfg = ''

      if len(t.attributes['SCRIPT']['ignore_cfg']) != 0:
        ignore_cfg = ' -ignore_cfg_file '+t.attributes['SCRIPT']['ignore_cfg'][0] 
      else:
        ignore_cfg = ''

      line = 'star_scan -f '+scan_sim_log+pass_cfg+fail_cfg+ignore_cfg

      if option.CHECK_LOG:
        line = line+' -log'

    elif TYPE == 'VERDI':

      compile_dir = solve_dir(option, 'FIND_GROUP', t, '0')
      seed = option.SEED



      assert len(t.attributes['ELABORATION']['tb_top']), exec014

      tb_top = t.attributes['ELABORATION']['tb_top'][0]

      define_opt=''

      for i in t.attributes['COMPILE']['define_opt']:

        if option.VENDOR == 'synopsys': 
          define_opt=define_opt+' '+i.replace(synopsys_cmd_pre['define_opt'], ' -define ')
        elif option.VENDOR == 'cadence': 
          define_opt=define_opt+' '+i.replace(cadence_cmd_pre['define_opt'], ' -define ')
        elif option.VENDOR == 'mentor': 
          define_opt=define_opt+' '+i.replace(mentor_cmd_pre['define_opt'], ' -define ')

      if option.VERDI_OPT == None:
        verdi_opt = define_opt 
      else:
        verdi_opt=define_opt+' '+option.VERDI_OPT

      # open wavefrom
      if seed != None and option.WAVEFORM:
        sim_dir = solve_dir(option, 'FIND_GROUP', t, option.SEED)
        assert os.path.exists(sim_dir), exec013
        fsdb_vif = sim_dir+'/sim.vif'
        fsdb = sim_dir+'/sim.fsdb'
        if os.path.isfile(fsdb_vif):
          verdi_opt = verdi_opt+' -ssf '+fsdb_vif
        elif os.path.isfile(fsdb):
          verdi_opt = verdi_opt+' -ssf '+fsdb

      line = 'star_verdi -cmp_dir '+compile_dir
      line = line+' '+tb_top
      line = verdi_opt != '' and line+'-verdi_opt "'+verdi_opt+'"' or line  

    elif TYPE == 'ENV':  
      regression_dir = solve_dir(option, 'FIND_REGRESSION', t, 0)

      line = 'export  VAR_SESSION="'+t.sessionname+'"\n'
      line = line+'export  VAR_GROUP="'+t.groupname+'"\n'
      line = line+'export  VAR_TEST="'+t.testname+'"\n'
      line = line+'export  VAR_COMP_DIR="'+compile_dir+'"\n'
      line = line+'export  VAR_SIM_DIR="'+sim_dir+'"\n'
      line = line+'export  VAR_TOP_DIR="'+regression_dir+'"\n'
      line = line+'export  VAR_ITERATION_NUM="'+str(index)+'"\n'

      if option.DUMPWAVE: 
        line = line+'export  STARBLAZE_FSDB_DUMP="on"\n'
      else: 
        line = line+'export  STARBLAZE_FSDB_DUMP="off"\n'

      abandon_list = [
       'comp_dir',
       'sim_dir',
       'top_dir'
      ]

      for k in t.attributes.keys():
        for l in t.attributes[k].keys():
          if l not in abandon_list: 
            value =''
            for m in t.attributes[k][l]: 
              if value =='':
                value = str(m)
              else:
                value = value+' '+str(m)
            line=line+'export VAR_'+l.upper()+'="'+value+'"\n'

  return line+'\n'


